<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<!--
Not Automatically generated, changed!:
$Id: script_ref_execution_model_perf_cons.htm,v 1.2 2011/04/29 20:11:14 wilbertd Exp $ 
-->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Scripting reference - The script execution model - Performance
considerations</title>
<link rel="stylesheet" type="text/css" href="../avisynth.css">
</head>
<body>
<h2>The script execution model - Performance considerations</h2>
<p>This section presents some performance-related issues that originate from the
way AviSynth scripts are executed; it also provides advice on how to optimise
your scripts and AviSynth configuration so that your scripts are parsed and/or
encoded faster.</p>
<a name="Plugin_auto-loading"></a>
<h3><span class="mw-headline">Plugin auto-loading</span></h3>
<p>An important thing to note is that auto-loading although is a convenient
method to have all your favorite filters on hands, it <i>does</i>  incur a speed
penalty. The penalty is twofold:</p>
<ol>
  <li>The loading, registering and unloading of plugins takes some time. The
    parsing of .avsi scripts also takes some time. This time, although small, is
    payed <i>in every</i> AviSynth script invocation.</li>
  <li>The registering of many functions and globals increases the size of
    internal AviSynth data structures, which on turn increases the seek time to
    locate a filter / variable during the parsing phase as well as during
    runtime script parsing.</li>
</ol>
<p>For small scripts and / or small number of auto-loading plugins the ease of
use outweights the above speed penalty (since there is also a speed penalty in
writing a lot of <a href="syntax_plugins.htm" title="LoadPlugin">LoadPlugin</a>
calls in every script that needs them). However if you regularly write large and
complex scripts and have a large number of plugins / include scripts in your
AviSynth plugin folder, you should consider a more granular approach to increase
overall script parsing / encoding performance.</p>
<p>For example, you could group <a href="syntax_plugins.htm" title="LoadPlugin">LoadPlugin</a>
calls for related plugins in separate .avsi scripts and have a central .avsi
script with a config function that loads different .avsi scripts depending on
its arguments. Then place in the plugin folder only the central .avsi script and
the bare-essential plugins that you use almost every time.</p>
<a name="Frame_caching_and_the_effect_on_spliting_filter_graph.27s_paths"></a>
<h3><span class="mw-headline">Frame caching and the effect on spliting filter
graph's paths</span></h3>
<p>In order to improve performance AviSynth places, transparently to script
writers, a specialised Cache filter just after each filter. The purpose of the
cache is to avoid the computationally expensive generation of a video frame that
has recently been created; if the frame is in the cache then it is returned
immediately, avoiding a possibly long chain of filter calls.</p>
<p>The presence of the cache gives a speed and memory advantage to filter graphs
that split processing paths <i>as late as possible</i>. In our filter
graph example above, if instead of:</p>
<pre>ov = <a href="corefilters/avisource.htm">AviSource</a>(&quot;clip2.avi&quot;)
ov1 = <a href="corefilters/resize.htm" title="Lanczos4Resize">Lanczos4Resize</a>(ov, 280, 210)
ov2 = ov1.<a href="corefilters/invert.htm" title="Invert">Invert</a>()</pre>
<p>we have used the following code:</p>
<pre>ov = <a href="corefilters/avisource.htm">AviSource</a>(&quot;clip2.avi&quot;)
ov2 = ov
ov1 = <a href="corefilters/resize.htm" title="Lanczos4Resize">Lanczos4Resize</a>(ov, 280, 210)
ov2 = ov2.Lanczos4Resize(280, 210).<a href="corefilters/invert.htm" title="Invert">Invert</a>()</pre>
<p>then the respective part of the filter graph would have been:</p>
<pre>                                         ...
                                          |
AviSource(clip2) &lt;--+-- Lanczos4Resize &lt;--+-- Overlay &lt;--+          
                    |                                    |
                    +-- Lanczos4Resize &lt;-- Invert &lt;------+-- Overlay (filter graph's root)</pre>
<p>In the later case we would have one more filter (and cache) in the filter
chain and -more importantly- we would have to generate two resized frames for
each call by the host application to get a frame instead of one.</p>
<p>Therefore, always try to split processing paths as late as possible; it will
make your scripts faster.</p>
<a name="What_not_to_include_in_runtime_scripts"></a>
<h3><span class="mw-headline">What <i>not</i> to include in runtime scripts</span></h3>
<p>Although as said above, runtime scripts are parsed as regular scripts do and
thus every statement allowed to a regular script is allowed in a runtime script,
some statements are not advisable from a performance point of view.</p>
<p>The principal reason is that runtime script parsing occurs in <i>every</i>
frame requested. Therefore, as a rule of thumb, computationally expensive
actions should in general be placed outside the runtime environment (at the main
script) in order to be executed only once. This practice trades some start-up
overhead with savings during frame serving, which in general dominates the
overall clip rendering / encoding time; thus it is justified as an optimisation.
This is of course to be taken with a grain of salt because there are
circmustances where the application needs force the (balanced) use of such
statements.</p>
<p>Having said all that, let's see our not-to-do-in-runtime-scripts list (and
some interesting counter-examples):</p>
<ul>
  <li>The following actions should most of the time be avoided:
    <ul>
      <li>Importing a script.</li>
      <li>Loading a plugin.</li>
      <li>Defining a user function.</li>
    </ul>
  </li>
</ul>
<dl>
  <dd>Issuing them on every frame will slow down (maybe significantly) encoding
    speed and (subject to implementation details) eat valuable memory. Moreover,
    this overhead will be beared without returning significant gains. It is in
    general much better to place them at the main script.</dd>
  <dd>See however an example of acceptable use: <a href="http://forum.doom9.org/showthread.php?t=129191" class="external text" title="http://forum.doom9.org/showthread.php?t=129191" rel="nofollow">Subtitles
    from a changing text-file</a>.</dd>
</dl>
<ul>
  <li>Calling a lot of filters / functions inside the runtime script will slow
    down your encoding speed. Those filters will be created and destroyed on
    every frame; thus you pay initialisation/cleanup costs at every frame.</li>
</ul>
<dl>
  <dd>If you can, put not-essential for the runtime processing filter calls
    outside the runtime environment; break the runtime script in more scripts if
    you have to. For example, instead of doing this:</dd>
</dl>
<pre><a href="corefilters/avisource.htm">AviSource</a>(&quot;myclip.avi&quot;)
total_frames = <a href="syntax_clip_properties.htm" title="Clip properties">Framecount</a>()
<a href="corefilters/conditionalfilter.htm" title="ScriptClip">ScriptClip</a>(&quot;&quot;&quot;
    <a href="corefilters/levels.htm" title="Levels">Levels</a>(0, 0.9, 255, 5, 250)
    total_frames % current_frame &lt; 2&nbsp;? <a href="corefilters/flip.htm" title="FlipHorizontal">FlipHorizontal</a>&nbsp;: last
    <a href="corefilters/tweak.htm" title="Tweak">Tweak</a>(hue=18)
    <a href="corefilters/subtitle.htm" title="Subtitle">Subtitle</a>(&quot;frame: &quot; + <a href="syntax_internal_functions_conversion.htm">String</a>(current_frame), y=320)
    &quot;&quot;&quot;)</pre>
<p>do this:</p>
<pre><a href="corefilters/avisource.htm">AviSource</a>(&quot;myclip.avi&quot;)
total_frames = <a href="syntax_clip_properties.htm" title="Clip properties">Framecount</a>()
<a href="corefilters/levels.htm" title="Levels">Levels</a>(0, 0.9, 255, 5, 250)
<a href="corefilters/conditionalfilter.htm" title="ScriptClip">ScriptClip</a>(&quot;&quot;&quot;total_frames % current_frame &lt; 2&nbsp;? <a href="corefilters/flip.htm" title="FlipHorizontal">FlipHorizontal</a>&nbsp;: last&quot;&quot;&quot;)
<a href="corefilters/tweak.htm" title="Tweak">Tweak</a>(hue=18)
ScriptClip(&quot;&quot;&quot;<a href="corefilters/subtitle.htm" title="Subtitle">Subtitle</a>(&quot;frame: &quot; + <a href="syntax_internal_functions_conversion.htm">String</a>(current_frame), y=320)&quot;&quot;&quot;)</pre>
<ul>
  <li><a href="script_ref_arrays.htm" title="Arrays">Arrays</a>,
    due to their recursive, script-based implementation can be expensive to
    parse, especially if they host a large number of elements. Using them
    without paying attention to minimize operations will slow down your encoding
    speed.</li>
</ul>
<dl>
  <dd>See however an example of acceptable use: <a href="http://avslib.sourceforge.net/examples/example-016.html" class="external text" title="http://avslib.sourceforge.net/examples/example-016.html" rel="nofollow">Per
    frame filtering, exporting specific frame(s)</a> (note that FrameFilter is a
    wrapper around <a href="corefilters/conditionalfilter.htm" title="ScriptClip">ScriptClip</a>).</dd>
</dl>
<hr>
<p>Back to the <a href="script_ref_execution_model.htm" title="The script execution model">script
execution model</a>.</p>
<p><kbd>$Date: 2011/04/29 20:11:14 $</kbd></p>
</body>
</html>
